package com.song.dubbo3service.filter;

import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.RpcServiceContext;

/**
 * @Author SHI YUAN
 * @DATE 2022/2/8 5:20 PM
 * @Version 1.0
 * @Desc 服务调用耗时
 *
 */
@Slf4j
@Activate(group = CommonConstants.PROVIDER)
public class CallCostFilter implements Filter {

    /**
     * Always call invoker.invoke() in the implementation to hand over the request to the next filter node.
     *
     * @param invoker
     * @param invocation
     */
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {

        boolean hasEx = false;
        long startTime = System.currentTimeMillis();
        try {
            return invoker.invoke(invocation);
        }catch (Exception ex){
            hasEx = true;
            throw ex;
        }finally {
            String protocolVersion = "";
            String interfaceName = "";
            long endTime = System.currentTimeMillis();
            long costTime = endTime - startTime;
            RpcServiceContext serviceContext = RpcContext.getServiceContext();
            // 调用方ip
            String remoteHost = serviceContext.getRemoteHost();
            URL url = serviceContext.getUrl();
            if (url != null) {
                // 服务版本
                protocolVersion = url.getParameter(CommonConstants.DUBBO);
                // 接口名称
                interfaceName = url.getPath();
            }
            // 本机ip
            String localIp = serviceContext.getLocalHost();
            String remoteApplicationName = serviceContext.getRemoteApplicationName();
            log.info("[CallCostFilter] costTime:{}, hasEx:{}, remoteHost:{}, protocolVersion:{}, interfaceName:{}, localIp:{}, remoteApplicationName:{}",
                    costTime, hasEx, remoteHost, protocolVersion,interfaceName, localIp, remoteApplicationName);
        }
    }
}
